﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace RoiControllers
{
    public class URectangle : ShapeBase
    {
        #region 字段|属性
        #region 字段
        private Rectangle _rectangle;
        #endregion
        #region 属性
        public Rectangle Rectangle { get => _rectangle; set => _rectangle = value; }
        public int X { get => Rectangle.X; set => _rectangle.X = value; }
        public int Y { get => Rectangle.Y; set => _rectangle.Y = value; }
        public Point Point { get => new Point(X, Y); set => _rectangle.Location = value; }
        public int Width { get => Rectangle.Width; set => _rectangle.Width = value; }
        public int Height { get => Rectangle.Height; set => _rectangle.Height = value; }
        #endregion
        #endregion

        #region 构造函数
        public URectangle() : base() 
        { 
            Type = ShapeType.Rectangle;
            Rectangle = new Rectangle(0, 0, 100, 100); // 默认大小
        }
        public URectangle(int x, int y, int width, int height) : base() 
        {
            Type = ShapeType.Rectangle;
            Rectangle = new Rectangle(x, y, width, height);
        }
        #endregion

        #region 绘制图形
        /// <summary>绘制所有形状手柄 </summary>
        private void DrawHandles(Graphics graphics)
        {
            Rectangle rectangle = Rectangle;
            // 四个角的手柄
            DrawHandle(graphics, rectangle.Left, rectangle.Top);       // 左上角
            DrawHandle(graphics, rectangle.Right, rectangle.Top);      // 右上角
            DrawHandle(graphics, rectangle.Left, rectangle.Bottom);    // 左下角
            DrawHandle(graphics, rectangle.Right, rectangle.Bottom);   // 右下角
            // 计算中点位置                                                           
            int midX = rectangle.Left + rectangle.Width / 2;
            int midY = rectangle.Top + rectangle.Height / 2;
            // 四个边中点的手柄：左右上下
            //DrawHandle(graphics, rectangle.Left, midY);       // 左边中点
            //DrawHandle(graphics, rectangle.Right, midY);      // 右边中点
            DrawHandle(graphics, midX, rectangle.Top);          // 上边中点
            DrawHandle(graphics, midX, rectangle.Bottom);       // 下边中点

        }
        /// <summary> 在左右边框中间位置绘制垂直方向箭头（↓↓）  </summary>
        private void DrawVerticalDirectionArrows(Graphics graphics)
        {
            Rectangle rectangle = Rectangle;
            // 1、计算左右边框的中间X坐标
            int leftMidX = rectangle.Left;
            int rightMidX = rectangle.Right;
            int verticalCenterY = rectangle.Top + rectangle.Height / 2;
            // 2、箭头大小（根据矩形大小自适应）
            int arrowSize = Math.Min(10, rectangle.Height / 4);
            int arrowHalfSize = arrowSize / 2;
            // 3、绘制箭头
            using (Pen arrowPen = new Pen(BackColor, BorderWidth + 1))
            {
                // 3.1 左侧向下箭头（垂直方向）
                Point leftArrowCenter = new Point(leftMidX, verticalCenterY + arrowSize);
                Point leftArrowRight = new Point(leftMidX + arrowHalfSize, verticalCenterY + arrowSize / 2);
                Point leftArrowLeft = new Point(leftMidX - arrowHalfSize, verticalCenterY + arrowHalfSize);
                graphics.DrawLine(arrowPen, leftArrowRight, leftArrowCenter);
                graphics.DrawLine(arrowPen, leftArrowLeft, leftArrowCenter);
                // 3.2 右侧向下箭头（垂直方向）
                Point rightArrowCenter = new Point(rightMidX, verticalCenterY + arrowSize);
                Point rightArrowLeft = new Point(rightMidX - arrowHalfSize, verticalCenterY + arrowHalfSize);
                Point rightArrowRight = new Point(rightMidX + arrowHalfSize, verticalCenterY + arrowHalfSize);
                graphics.DrawLine(arrowPen, rightArrowLeft, rightArrowCenter);
                graphics.DrawLine(arrowPen, rightArrowRight, rightArrowCenter);
            }
        }
        /// <summary> 绘制区域中心位置 </summary>
        private void DrawRegionCenter(Graphics graphics)
        {
            Rectangle rectangle = Rectangle;
            // 1、计算矩形中心坐标
            int centerX = rectangle.X + rectangle.Width / 2;
            int centerY = rectangle.Y + rectangle.Height / 2;
            // 2、线长度大小（根据矩形大小自适应）
            int lineHalfLength = 3;
            // 3、绘制箭头
            using (Pen arrowPen = new Pen(BackColor, BorderWidth))
            {
                // 3.1 水平线
                Point left = new Point(centerX - lineHalfLength, centerY);
                Point right = new Point(centerX + lineHalfLength, centerY);
                graphics.DrawLine(arrowPen, left, right);
                // 3.2 垂直线
                Point top = new Point(centerX, centerY - lineHalfLength);
                Point bottom = new Point(centerX, centerY + lineHalfLength);
                graphics.DrawLine(arrowPen, top, bottom);
            }
        }
        /// <summary> 绘制形状文本描述 </summary>
        private void DrawDescription(Graphics graphics)
        {
            using (SolidBrush brush = new SolidBrush(Color.LightGreen))
            {
                Font descriptionFont = new Font("Arial", 9);
                SizeF maxTextSize = graphics.MeasureString(Description, descriptionFont);
                float x = X + Width / 2 - maxTextSize.Width / 2;
                float y = Y + Height / 2 - maxTextSize.Height;
                graphics.DrawString(Description, descriptionFont, brush, x, y);
            }
        }
        #endregion

        #region 方法重写：绘制形状相关
        public override void Rotate(PointF point)
        {
            ExceteRotateCallback(this);
        }
        public override void Move(PointF point)
        {
            int dx = (int)(point.X - LastLocation.X);
            int dy = (int)(point.Y - LastLocation.Y);
            X += dx;
            Y += dy;
            LastLocation = point;
            ExceteMoveCallback(this);
        }
        public override void Resize(PointF pointF)
        {
            Rectangle rect = Rectangle;
            Point point = new Point((int)pointF.X, (int)pointF.Y);
            switch (HandleType)
            {
                case ShapeHandleType.TopLeft:
                    rect.X = point.X;
                    rect.Y = point.Y;
                    rect.Width = Rectangle.Right - point.X;
                    rect.Height = Rectangle.Bottom - point.Y;
                    break;
                case ShapeHandleType.TopRight:
                    rect.Y = point.Y;
                    rect.Width = point.X - Rectangle.Left;
                    rect.Height = Rectangle.Bottom - point.Y;
                    break;
                case ShapeHandleType.BottomLeft:
                    rect.X = point.X;
                    rect.Width = Rectangle.Right - point.X;
                    rect.Height = point.Y - Rectangle.Top;
                    break;
                case ShapeHandleType.BottomRight:
                    rect.Width = point.X - Rectangle.Left;
                    rect.Height = point.Y - Rectangle.Top;
                    break;
                // 四个边中点的手柄（新增）
                case ShapeHandleType.Top:       // 上边中点：调整高度（Y方向）
                    rect.Y = point.Y;
                    rect.Height = Rectangle.Bottom - point.Y;
                    break;
                case ShapeHandleType.Right:    // 右边中点：调整宽度（X方向）
                    rect.Width = point.X - Rectangle.Left;
                    break;
                case ShapeHandleType.Bottom:    // 下边中点：调整高度（Y方向）
                    rect.Height = point.Y - Rectangle.Top;
                    break;
                case ShapeHandleType.Left:     // 左边中点：调整宽度（X方向）
                    rect.X = point.X;
                    rect.Width = Rectangle.Right - point.X;
                    break;
            }
            if (rect.Width > 15 && rect.Height > 15)
            {
                Rectangle = rect;
            }
            ExceteResizeCallback(this);
        }
        public override void DrawShapeWithHandle(Graphics graphics)
        {
            BackColor = SelectedColor;
            Color current = BackColor;
            Pen pen = new Pen(BackColor, BorderWidth);
            //0、绘制背景区域轮廓
            graphics.DrawRectangle(pen, Rectangle);
            //0、绘制中心
            DrawRegionCenter(graphics);
            if (IsSelected)
            {
                // 1、填充背景区域
                using (SolidBrush brush = new SolidBrush(Color.FromArgb(Alpha, BackColor)))
                {
                    graphics.FillRectangle(brush, Rectangle);
                }
                // 2、 绘制水平方向箭头
                DrawVerticalDirectionArrows(graphics);
                
                // 3、绘制形状手柄
                DrawHandles(graphics);
            }
            // 4、绘制形状描述
            DrawDescription(graphics);
        }
        public override void DrawHandle(Graphics graphics, int x, int y)
        {
            Rectangle handleRect = new Rectangle(x - HandleSize / 2, y - HandleSize / 2, HandleSize, HandleSize);
            using (var brush = new SolidBrush(Color.FromArgb(Alpha*2, HandleColor)))
            {
                graphics.FillRectangle(brush, handleRect);
            }
            Pen pen = new Pen(HandleColor, BorderWidth);
            graphics.DrawRectangle(pen, handleRect);
        }
        public override void DrawHandle(Graphics graphics, float x, float y)
        {

        }
        public override void DrawHandle(Graphics graphics, PointF point)
        {

        }
        public override ShapeHandleType GetHandleType(PointF point)
        {
            Rectangle rectangle = Rectangle;
            // 计算中点坐标
            int midX = rectangle.Left + rectangle.Width / 2;
            int midY = rectangle.Top + rectangle.Height / 2;
            // 四个角的手柄
            if (IsInHandle(point, new Point(rectangle.Left, rectangle.Top)))
                return ShapeHandleType.TopLeft;
            if (IsInHandle(point, new Point(rectangle.Right, rectangle.Top)))
                return ShapeHandleType.TopRight;
            if (IsInHandle(point, new Point(rectangle.Left, rectangle.Bottom)))
                return ShapeHandleType.BottomLeft;
            if (IsInHandle(point, new Point(rectangle.Right, rectangle.Bottom)))
                return ShapeHandleType.BottomRight;
            // 四个边中点的手柄
            if (IsInHandle(point, new Point(midX, rectangle.Top)))
                return ShapeHandleType.Top;
            if (IsInHandle(point, new Point(rectangle.Right, midY)))
                return ShapeHandleType.Right;
            if (IsInHandle(point, new Point(midX, rectangle.Bottom)))
                return ShapeHandleType.Bottom;
            if (IsInHandle(point, new Point(rectangle.Left, midY)))
                return ShapeHandleType.Left;
            return ShapeHandleType.None;
        }
        public override Cursor GetSystemHandleType(PointF point)
        {
            switch (GetHandleType(point))
            {
                // 四个角方向的手柄
                case ShapeHandleType.TopLeft:
                case ShapeHandleType.BottomRight:
                    return Cursors.SizeNWSE;
                case ShapeHandleType.TopRight:
                case ShapeHandleType.BottomLeft:
                    return Cursors.SizeNESW;
                // 四个边中点的手柄
                case ShapeHandleType.Top:
                case ShapeHandleType.Bottom:
                    return Cursors.SizeNS; 
                case ShapeHandleType.Left:
                case ShapeHandleType.Right:
                    return Cursors.SizeWE; 
                default: 
                    return Cursors.Default;
            }
        }
        public override bool IsInRegion(PointF point)
        {
            return (GetHandleType(point) != ShapeHandleType.None) 
                || Rectangle.Contains(new Point((int)point.X, (int)point.Y));
        }
        public override bool IsInBackground(PointF point)
        {
            return Rectangle.Contains(new Point((int)point.X, (int)point.Y)) 
                && !(GetHandleType(point) != ShapeHandleType.None);
        }
        public override bool IsInHandle(PointF inPoint, PointF point)
        {
            // 增大检测范围
            int detectionSize = HandleOutSize + 2;
            RectangleF handleRect = new RectangleF(  point.X - detectionSize / 2,  point.Y - detectionSize / 2, 
                detectionSize, detectionSize );
            return handleRect.Contains(inPoint);
        }
        public override bool IsInRotateHandle(PointF point)
        {
            return false;
        }
        #endregion

        #region 方法重写：形状变更事件
        public override void ExceteMoveCallback(ShapeBase obj)
        {
            MoveEvents?.Invoke(this, Rectangle.Location);
        }
        public override void ExceteRotateCallback(ShapeBase obj)
        {
            RotateEvents?.Invoke(this, Rectangle.Location);
        }
        public override void ExceteResizeCallback(ShapeBase obj)
        {
            ResizeEvents?.Invoke(this, Rectangle.Location);
        }
        public override void ExceteAttachCallback(ShapeBase obj)
        {
            AttachEvents?.Invoke(this, Rectangle.Location);
        }
        public override void ExceteDetachCallback(ShapeBase obj)
        {
            DetachEvents?.Invoke(this, Rectangle.Location);
        }
        public override void ExceteSelectedCallback(ShapeBase obj)
        {
            SelectedEvents?.Invoke(this, Rectangle.Location);
        }
        #endregion

    }
}
